import { Cartesian3, PostProcessStage } from 'cesium';
import { isNil } from 'lodash';
import { useEffect } from 'react';
import { useCesium } from 'resium';
import { useAppSelector } from '../../../../store';
import { CesiumMath } from '../../../../utils/Type';

const FS_Snow = `
     uniform sampler2D colorTexture;
      in vec2 v_textureCoordinates;
      uniform float snowSpeed;

      float snow(vec2 uv,float scale){
        float time = czm_frameNumber / snowSpeed;
        float w = smoothstep(1., 0., -uv.y*(scale/10.));
        if(w < 0.1) return 0.;
        uv += time/scale;
        uv.y += time*2./scale;
        uv.x += sin(uv.y + time*0.5)/scale;
        uv *= scale;
        vec2 s = floor(uv);
        vec2 f = fract(uv);
        vec2 p;
        float k = 3., d;
        p = 0.5 + 0.35*sin(11.*fract(sin((s + scale)*mat2(7, 3, 6, 5))*5.)) - f;
        d = length(p);
        k = min(d, k);
        k = smoothstep(0., k, sin(f.x + f.y)*0.01);
        return k*w;
      }

      out vec4 vFragColor;

      void main(void){
        vec2 resolution = czm_viewport.zw;
        vec2 uv = (gl_FragCoord.xy*2. - resolution.xy) / min(resolution.x, resolution.y);
        vec3 finalColor = vec3(0);
        float c = 0.0;
        c += snow(uv, 50.) * 0.0;
        c += snow(uv, 30.) * 0.0;
        c += snow(uv, 10.) * 0.0;
        c += snow(uv, 5.);
        c += snow(uv, 4.);
        c += snow(uv, 3.);
        c += snow(uv, 2.);
        finalColor = vec3(c);
        vFragColor = mix(texture(colorTexture, v_textureCoordinates), vec4(finalColor, 1), 0.3);
      }
`;

export default function Demo() {
    const { viewer } = useCesium();
    const pos = useAppSelector((state) => state.scene.initPosition);

    useEffect(() => {
        if (isNil(viewer)) return;

        let lastStage: PostProcessStage | null = null;

        // 移除
        const removeStage = () => {
            lastStage && viewer.scene.postProcessStages.remove(lastStage);
            lastStage = null;
        };

        // 雪
        const handleSnow = (snowSpeed: number) => {
            removeStage();
            const snow = new PostProcessStage({
                name: 'hi_snow',
                fragmentShader: FS_Snow,
                uniforms: {
                    snowSpeed, // 雪速
                },
            });
            viewer.scene.postProcessStages.add(snow);
            lastStage = snow;
        };

        handleSnow(60.0); // 调用方式

        const target = Cartesian3.fromDegrees(pos.longitude, pos.latitude, 1000);
        viewer.camera.setView({
            destination: target,
            orientation: {
                heading: viewer.camera.heading,
                pitch: CesiumMath.toDegrees(0),
                roll: viewer.camera.roll,
                up: Cartesian3.clone(Cartesian3.UNIT_Y),
            },
        });

        return () => {
            removeStage();
        };
    }, [pos, viewer]);
    return null;
}
